package main

import (
	"net/http"
	"os"
	"strings"

	"github.com/gin-gonic/gin"
	jsoniter "github.com/json-iterator/go"

	"github.com/eidng8/go-simple-tree/ent"
	"github.com/eidng8/go-simple-tree/ent/schema"
)

var json = jsoniter.ConfigCompatibleWithStandardLibrary

type Server struct {
	EC      *ent.Client
	BaseURL string
}

func (s Server) BaseUrl() string {
	return strings.TrimRight(s.BaseURL, "/") + "/" +
		strings.TrimLeft(schema.BaseUri, "/")
}

var _ StrictServerInterface = (*Server)(nil)

func newServer(entClient *ent.Client) Server {
	return Server{
		EC:      entClient,
		BaseURL: os.Getenv("BASE_URL"),
	}
}

func newEngine(entClient *ent.Client) (*Server, *gin.Engine, error) {
	swagger, err := GetSwagger()
	if err != nil {
		return &Server{}, nil, err
	}
	swagger.Servers = nil
	getEnvWithDefault(gin.EnvGinMode, gin.ReleaseMode)
	engine := gin.Default()
	server := newServer(entClient)
	handler := NewStrictHandler(server, []StrictMiddlewareFunc{})
	RegisterHandlers(engine, handler)
	// RegisterHandlersWithOptions(
	// 	engine, handler, GinServerOptions{
	// 		ErrorHandler: func(ctx *gin.Context, err error, code int) {
	// 			// This doesn't work since the error is generated by fmt.Errorf().
	// 			// Such error cannot be converted to err.ValidationError.
	// 			if ent.IsValidationError(err) {
	// 				code = http.StatusUnprocessableEntity
	// 			}
	// 			ctx.JSON(code, gin.H{"error": err.Error()})
	// 		},
	// 	},
	// )
	return &server, engine, nil
}

// handleErrorResponse replaces oapi-codegen generated error handling.
func handleErrorResponse(ctx *gin.Context, err error) {
	_ = ctx.Error(err)
	switch {
	case ent.IsValidationError(err):
		ctx.Status(http.StatusUnprocessableEntity)
	case ent.IsNotFound(err):
		ctx.Status(http.StatusNotFound)
	default:
		ctx.Status(http.StatusInternalServerError)
	}
}

func getEnvWithDefault(name, defVal string) string {
	val := os.Getenv(name)
	if "" == val {
		return defVal
	}
	return val
}
